﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure;
using System.IO;
using System.Configuration;

namespace bdtheque.azure.business.azurestorage
{
    public class CloudBlobHelper
    {
        #region Private Members
        private CloudStorageAccount cloudStorageAccount;
        #endregion

        #region Constructors
        public CloudBlobHelper(CloudStorageAccount _cloudStorageAccount)
        {
            cloudStorageAccount = _cloudStorageAccount;
        }
        #endregion

        #region Public Methods
        public string UploadBlob(string blobContainerReference, string filePath, string contentType, bool allowPublicAcces, bool deleteUploadedFile)
        {
            // Create blob client
            var blobClient = cloudStorageAccount.CreateCloudBlobClient();
            blobClient.RetryPolicy = RetryPolicies.Retry(5, TimeSpan.FromSeconds(5));

            // Get specific container reference for the client
            var blobContainer = blobClient.GetContainerReference(blobContainerReference.ToLower());

            // Get reference to blob
            var blob = blobContainer.GetBlobReference(Path.GetFileName(filePath));
            blob.Properties.ContentType = contentType;

            // Upload file from the local system to the blob
            blob.UploadFile(filePath);

            // Delete file from local systeme
            if(deleteUploadedFile)
                File.Delete(filePath);

            return blob.Uri.AbsoluteUri;
        }

        public string UploadBlobFromStream(string blobContainerReference, Stream fileStream, string fileName, string contentType, bool allowPublicAcces)
        {
            // Create blob client
            var blobClient = cloudStorageAccount.CreateCloudBlobClient();
            blobClient.RetryPolicy = RetryPolicies.Retry(5, TimeSpan.FromSeconds(5));

            // Get specific container reference for the client
            var blobContainer = blobClient.GetContainerReference(blobContainerReference.ToLower());

            // Get reference to blob
            var blob = blobContainer.GetBlobReference(fileName);
            blob.Properties.ContentType = contentType;

            // Upload file from the local system to the blob
            blob.UploadFromStream(fileStream);

            return blob.Uri.AbsoluteUri;
        }

        public void DownloadBlob(string blobContainerReference, string blobAbsoluteUri, string filePath)
        {
            // Create blob client
            var blobClient = cloudStorageAccount.CreateCloudBlobClient();
            blobClient.RetryPolicy = RetryPolicies.Retry(5, TimeSpan.FromSeconds(5));

            // Get specific container reference for the client
            var blobContainer = blobClient.GetContainerReference(blobContainerReference.ToLower());

            // Get blob containing the file
            var blob = blobContainer.GetBlobReference(blobAbsoluteUri);

            // Download the file from blob to local systeme
            blob.DownloadToFile(filePath);
        }

        public void DeleteBlob(string blobContainerReference, string blobAbsoluteUri)
        {
            // Create blob client
            var blobClient = cloudStorageAccount.CreateCloudBlobClient();
            blobClient.RetryPolicy = RetryPolicies.Retry(5, TimeSpan.FromSeconds(5));

            // Get specific container reference for the client
            var blobContainer = blobClient.GetContainerReference(blobContainerReference.ToLower());

            // Get blob containing for delete operation
            var blob = blobContainer.GetBlobReference(blobAbsoluteUri);

            // Delete blob
            blob.Delete();
        }

        public DateTime GetBlobLastModifiedDate(string blobContainerReference, string blobAbsoluteUri)
        {
            // Create blob client
            var blobClient = cloudStorageAccount.CreateCloudBlobClient();
            blobClient.RetryPolicy = RetryPolicies.Retry(5, TimeSpan.FromSeconds(5));

            // Get specific container reference for the client
            var blobContainer = blobClient.GetContainerReference(blobContainerReference.ToLower());

            // Get blob containing for delete operation
            var blob = blobContainer.GetBlobReference(blobAbsoluteUri);

            // Get last modified 
            try
            {                
                blob.FetchAttributes();
                return blob.Properties.LastModifiedUtc;
            }
            catch (StorageClientException e)
            {
                if (e.ErrorCode == StorageErrorCode.ResourceNotFound)
                {
                    // If the blob does not exists return a generic Date
                    return new DateTime();
                }
                else
                {
                    throw;
                }
            }
        }

        public string GetBlobSharedAccessSignature(string blobContainerReference, string fileName, bool allowPublicAcces)
        {
            // Create blob client
            var blobClient = cloudStorageAccount.CreateCloudBlobClient();
            blobClient.RetryPolicy = RetryPolicies.Retry(5, TimeSpan.FromSeconds(5));

            // Get specific container reference for the client
            var blobContainer = blobClient.GetContainerReference(blobContainerReference.ToLower());

            // Get reference to blob
            var blob = blobContainer.GetBlobReference(fileName);

            var sharedAccessPolicy = new SharedAccessPolicy();
            sharedAccessPolicy.Permissions = SharedAccessPermissions.Read;
            sharedAccessPolicy.SharedAccessExpiryTime = DateTime.Now.AddMinutes(5);

            return blob.GetSharedAccessSignature(sharedAccessPolicy);
        }
        #endregion
    }
}
